package cn.zzf.leetcode;

/**
 * 给你两个整数，被除数 dividend 和除数 divisor。将两数相除，要求 不使用 乘法、除法和取余运算。
 * <p>
 * 整数除法应该向零截断，也就是截去（truncate）其小数部分。例如，8.345 将被截断为 8 ，-2.7335 将被截断至 -2 。
 * <p>
 * 返回被除数 dividend 除以除数 divisor 得到的 商 。
 * <p>
 * 注意：假设我们的环境只能存储 32 位 有符号整数，其数值范围是 [−2^31,  2^31 − 1] 。本题中，如果商 严格大于 2^31 − 1 ，则返回 231 − 1 ；如果商 严格小于 -2^31 ，则返回 -2^31 。
 * <pre>{@code
 * 示例 1:
 * 输入: dividend = 10, divisor = 3
 * 输出: 3
 * 解释: 10/3 = 3.33333.. ，向零截断后得到 3 。
 *
 * 示例 2:
 * 输入: dividend = 7, divisor = -3
 * 输出: -2
 * 解释: 7/-3 = -2.33333.. ，向零截断后得到 -2 。
 *
 * 提示：
 * -2^31 <= dividend, divisor <= 2^31 - 1
 * divisor != 0
 * }</pre>
 *
 * @author zzf
 */
public class T0029_Divide {
    public static int divide(int dividend, int divisor) {
        // 特殊情况处理
        if (dividend == 0) {
            return 0;
        }
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }
        if (divisor == 1) {
            return dividend;
        }
        if (divisor == -1) {
            return -dividend;
        }
        if (divisor > dividend && dividend > 0 || divisor < dividend && dividend < 0) {
            return 0;
        }
        boolean isNegative = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
        dividend = Math.abs(dividend);
        divisor = Math.abs(divisor);
        int result = 0;
        int quotient = 1;
        while (dividend >= divisor) {
            for (int i = 1; i < dividend; i++) {
                if (dividend >= divisor + divisor) {
                    divisor += divisor;
                    quotient += quotient;
                    result += quotient;
                } else {
                    dividend -= divisor;
                    quotient = 1;
                    result += quotient;
                    break;
                }
            }
        }


        return isNegative ? -result : result;
    }

    public static void main(String[] args) {
        System.out.println(divide(25, 5));
        System.out.println(divide(10, 3));
        System.out.println(divide(100_000_000, 99));
    }

}
